﻿var gameDao = require("./../dao/gameDao");
var gameConfig = require("./../config/gameConfig");
var redis_laba_win_pool = require("./../../util/redis_laba_win_pool");
let log = require("./../../util/loginfo").getInstand;

arithmetic = function (_idx) {
	//相关属性

	//可选择倍数
	var betCount = [1, 10, 20, 50, 100];

	//分数数组
	this.scoreArr = {};

	//虚拟奖池
	this.virtual_score_pool = 1000000;
	//实际奖池
	this.score_pool = [];

	//========================================
	//水位
	this.nGamblingWaterLevelGold = 0;
	//库存
	this.nGamblingBalanceGold = 0;
	//奖池
	this.nGamblingWinPool = 0;
	//大奖幸运等级
	this.nGamblingBigWinLevel = [];
	//大奖幸运概率
	this.nGamblingBigWinLuck = [];

	this.printPool = function () {
		for (var i = 0; i < betCount.length; ++i) {
			log.info("i:" + i + "-" + this.score_pool[i]);
		}
	};

	//获得实际奖池
	this.getScorePool = function (_betIdx) {
		if (this.score_pool[_betIdx]) {
			this.printPool();
			return this.score_pool[_betIdx];
		} else {
			//this.printPool();
			return 0
		}

	};

	this.getScorePoolList = function () {
		return this.score_pool;
	};

	this.getScorePoolListLength = function () {
		return betCount.length;
	};

	this.getScoreId = function () {
		return betCount;
	};


	this.getGamblingBalanceGold = function () {
		//获取库存 奖池   数据库同步使用
		var dict = {
			nGamblingBalanceGold: this.nGamblingBalanceGold,
			nGamblingWinPool: this.nGamblingWinPool
		};

		return dict;

	};
	this.addGamblingBalanceGold = function (Gold, Pool) {
		//添加库存 奖池   数据库同步使用
		this.nGamblingBalanceGold += parseInt(Gold);
		this.nGamblingWinPool += parseInt(Pool);
		log.info("添加库存:" + Gold);
		log.info("添加奖池:" + Pool);
		log.info(this.nGamblingBalanceGold);
		log.info(this.nGamblingWinPool);
		//redis存储奖池
		redis_laba_win_pool.redis_win_pool_incrby(parseInt(Pool))
	};
	this.subGamblingBalanceGold = function (Gold, Pool) {
		//减少库存   奖池 数据库同步使用
		//this.nGamblingBalanceGold-= parseInt(Gold);
		this.nGamblingWinPool -= parseInt(Pool);
		log.info("减少库存:" + Gold);
		log.info("减少奖池:" + Pool);
		log.info(this.nGamblingBalanceGold);
		log.info(this.nGamblingWinPool);

		//redis减少奖池
		redis_laba_win_pool.redis_win_pool_decrby(parseInt(Pool));
	};
	this.getGamblingBalanceLevelBigWin = function () {
		//获取库存  水位 奖池 幸运值   判断中奖使用
		var value = {
			nGamblingWaterLevelGold: this.nGamblingWaterLevelGold,
			nGamblingBalanceGold: this.nGamblingBalanceGold,
			nGamblingWinPool: this.nGamblingWinPool,
			nGamblingBigWinLevel: this.nGamblingBigWinLevel,
			nGamblingBigWinLuck: this.nGamblingBigWinLuck
		};
		return value;
	};

	//获得奖池
	this.getVirtualScorePool = function () {
		//var result = {virtual_score_pool:this.virtual_score_pool,score_pool}
		return this.virtual_score_pool;
	};

	this.init = function () {
		//初始化水位和库存
		this.initGamblingGame();
	};

	//=================================================================================================
	this.initGamblingGame = function () {
		var self = this;
		gameDao.getGamblingGame(function (Result) {

			self.nGamblingWaterLevelGold = Result[0].nGamblingWaterLevelGold;  //水位
			self.nGamblingBalanceGold = Result[0].nGamblingBalanceGold;      //库存
			self.nGamblingWinPool = Result[0].nGamblingWinPool;      //奖池

			self.nGamblingBigWinLevel = Result[0].nGamblingBigWinLevel.split(',').map(Number);  //大奖幸运等级
			self.nGamblingBigWinLuck = Result[0].nGamblingBigWinLuck.split(',').map(Number);    //大奖幸运概率


			//redis存储奖池
			redis_laba_win_pool.redis_win_pool_incrby(self.nGamblingWinPool);


			log.info("读取采池数据完毕!");
			log.info("水位:" + self.nGamblingWaterLevelGold);
			log.info("库存:" + self.nGamblingBalanceGold);
			log.info("奖池:" + self.nGamblingWinPool);
			log.info("大奖幸运等级:" + self.nGamblingBigWinLevel);
			log.info("大奖幸运概率:" + self.nGamblingBigWinLuck);
		})


	};

	this.gameProcessor = function (betInfo_list, nGamblingWinPool) {
		// ZZZ-20230513,
		let all_bet_list = [0, 0, 0, 0, 0, 0]; // 下注金额数组
		let all_bet_sort = [[0,0], [1,0], [2,0], [3,0], [4,0], [5,0]]; // 排序下注数组
		let pay_bet_list = []; // 能够赔付的数组
		let bet_all = 0; // 总共下注
		let flg_color = true; // 是否可以出相同的颜色

		for (let i in betInfo_list) {
			let betInfo = betInfo_list[i];
			let idx = parseInt(betInfo.bet_res);
			let bet = parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]);

			if (betInfo["isRobot"]) {
				continue;
			}
			bet_all += bet;
			all_bet_list[idx] += bet;
			all_bet_sort[idx][1] += (bet * 6); // 中间值
		}
		// 按照赔付金额从小到大排序
		all_bet_sort.sort(function(a, b) {
			return (a[1] > b[1]) ? 1 : -1;
		});
		for (let i in all_bet_sort) {
			let idx = all_bet_sort[i][0];
			let pay = all_bet_sort[i][1];
			let bet = all_bet_list[idx];

			if (pay <= 0 || pay <= (nGamblingWinPool/100)) { // 金额占比很小
				pay_bet_list.push(idx);
			} else {
				if (pay <= (nGamblingWinPool/10)) { // 奖金要留有余量
					if ((bet / bet_all) <= 0.85) { // 消除峰值
						pay_bet_list.push(idx);
						flg_color = false;
						log.info("idx=" + idx + ", <= 0.85, pushed");
					}
				} else {
					/*if (Math.abs(pay - bet_all) <= (bet_all*0.15)) { // 有差不多可以对冲的数额
						pay_bet_list.push(idx);
						log.info("idx=" + idx + ", <= 0.15, pushed");
					}*/
				}
			}
		}
		log.info("gameProcessor all_bet_sort=" + JSON.stringify(all_bet_sort));
		log.info("gameProcessor pay_bet_list=" + JSON.stringify(pay_bet_list));

		//决定结果
		let win_array = [];
		let winType = 0;
		let idx = 0;
		let test_1 = -1;
		let test_2 = -1;
		let test_3 = -1;
		// 赔付判断
		if (pay_bet_list.length <= 3) { // 都不够赔付或不足四个，选最小的
			win_array = PayMinimize([all_bet_sort[0][0],all_bet_sort[1][0],all_bet_sort[2][0]], all_bet_list);
			test_1 = win_array[0];
			test_2 = win_array[1];
			test_3 = win_array[2];
			log.info("~~~~~~~~~~~~~~~ 都不够赔付，选最小的赔付, 位置=" + JSON.stringify(win_array));
		} else {
			if (flg_color) { // 是否可以出相同的颜色
				test_1 = pay_bet_list[RandomNumBoth(0, pay_bet_list.length-1)];
				test_2 = pay_bet_list[RandomNumBoth(0, pay_bet_list.length-1)];
				test_3 = pay_bet_list[RandomNumBoth(0, pay_bet_list.length-1)];
			} else {
				idx = RandomNumBoth(0, pay_bet_list.length-1);
				test_1 = pay_bet_list[idx];
				pay_bet_list.splice(idx, 0, 1);

				idx = RandomNumBoth(0, pay_bet_list.length-1);
				test_2 = pay_bet_list[idx];
				pay_bet_list.splice(idx, 0, 1);

				idx = RandomNumBoth(0, pay_bet_list.length-1);
				test_3 = pay_bet_list[idx];
				pay_bet_list.splice(idx, 0, 1);
			}
		}

		win_array = [test_1, test_2, test_3];
		log.info("本局开奖" + JSON.stringify(win_array));

		if (test_1 === test_2 && test_2 === test_3) {
			winType = 0;
		} else if (test_1 === test_2) {
			winType = 1;
		} else if (test_2 === test_3) {
			winType = 2;
		} else if (test_1 === test_3) {
			winType = 3;
		} else {
			winType = 4;
		}
		//算账
		var user_win_list = {};    //用户赢钱字典
		var user_bet_sum_list = {};  //用户下注数字典
		var user_bet_true_list = [];  //用户压对数组
		var user_robot_dict = {};  //是否机器人字典
		for (let i in betInfo_list) {
			let betInfo = betInfo_list[i];    //下注详情
			let res = parseInt(betInfo.bet_res);
			if (!user_win_list[betInfo["userId"]]) {
				user_win_list[betInfo["userId"]] = 0;
			}
			if (!user_bet_sum_list[betInfo["userId"]]) {
				user_bet_sum_list[betInfo["userId"]] = 0;
			}
			user_bet_sum_list[betInfo["userId"]] += parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]);
			// log.info("判断结果-------------------------------")
			// log.info(win)
			// log.info(res)
			if (winType === 0) {
				if (res === win_array[0]) {
					if (user_bet_true_list.indexOf(betInfo["userId"]) === -1) {
						user_bet_true_list.push(betInfo["userId"]);
					}
					user_win_list[betInfo["userId"]] += parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]) * 9;
				}
			} else if (winType === 1) {
				if (res === win_array[0]) {
					if (user_bet_true_list.indexOf(betInfo["userId"]) === -1) {
						user_bet_true_list.push(betInfo["userId"]);
					}
					user_win_list[betInfo["userId"]] += parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]) * 3;
				} else if (res === win_array[2]) {
					if (user_bet_true_list.indexOf(betInfo["userId"]) === -1) {
						user_bet_true_list.push(betInfo["userId"]);
					}
					user_win_list[betInfo["userId"]] += parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]) * 2;
				}
			} else if (winType === 2) {
				if (res === win_array[1]) {
					if (user_bet_true_list.indexOf(betInfo["userId"]) === -1) {
						user_bet_true_list.push(betInfo["userId"]);
					}
					user_win_list[betInfo["userId"]] += parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]) * 3;
				} else if (res === win_array[0]) {
					if (user_bet_true_list.indexOf(betInfo["userId"]) === -1) {
						user_bet_true_list.push(betInfo["userId"]);
					}
					user_win_list[betInfo["userId"]] += parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]) * 2;
				}
			} else if (winType === 3) {
				if (res === win_array[2]) {
					if (user_bet_true_list.indexOf(betInfo["userId"]) === -1) {
						user_bet_true_list.push(betInfo["userId"]);
					}
					user_win_list[betInfo["userId"]] += parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]) * 3;
				} else if (res === win_array[1]) {
					if (user_bet_true_list.indexOf(betInfo["userId"]) === -1) {
						user_bet_true_list.push(betInfo["userId"]);
					}
					user_win_list[betInfo["userId"]] += parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]) * 2;
				}
			} else if (winType === 4) {
				for (let j = 0; j < win_array.length; j++) {
					if (res === win_array[j]) {
						if (user_bet_true_list.indexOf(betInfo["userId"]) === -1) {
							user_bet_true_list.push(betInfo["userId"]);
						}
						user_win_list[betInfo["userId"]] += parseInt(gameConfig.coinConfig[betInfo["bet_gold"]]) * 2;
					}
				}
			}

			user_robot_dict[betInfo["userId"]] = betInfo["is_robot"];

		}
		var dictAnalyseResults = {};
		win_array.sort(function (a, b) {
			return Math.random() > 0.5 ? -1 : 1;
		})
		dictAnalyseResults["win"] = win_array;
		dictAnalyseResults["win_res"] = win_array;

		dictAnalyseResults["win_user_list"] = user_win_list;  //# 用户获奖结果
		dictAnalyseResults["user_bet_sum_list"] = user_bet_sum_list;  //用户下注字典
		dictAnalyseResults["user_bet_true_list"] = user_bet_true_list;  //用户神算子数组
		dictAnalyseResults["user_robot_dict"] = user_robot_dict;  //是否机器人数组

		return dictAnalyseResults
		//开奖算法

	};


	this.init();

};

// 最小赔付
function PayMinimize(aIdx, aBet) {
	// 1.最小值*9
	let nVl1 = aBet[aIdx[0]] * 9;
	// 2.最小值*3 + 次小值*2
	let nVl2 = aBet[aIdx[0]] * 3 + aBet[aIdx[1]] * 2;
	// 3.三个值*2相加
	let nVl3 = aBet[aIdx[0]] * 2 + aBet[aIdx[1]] * 2 + aBet[aIdx[2]] * 2;

	if (nVl1 <= nVl2 && nVl1 <= nVl3) {
		return [aIdx[0], aIdx[0], aIdx[0]];
	}
	if (nVl2 <= nVl1 && nVl2 <= nVl3) {
		if (Math.random() < 0.7) { // 有一定概率的扰动，真实一点
			return [aIdx[0], aIdx[0], aIdx[1]];
		}
	}

	return [aIdx[0], aIdx[1], aIdx[2]];
}

function RandomNumBoth(Min, Max) {
	//生成指定范围内随机整数
	var Range = Max - Min;
	var Rand = Math.random();
	var num = Min + Math.round(Rand * Range); //四舍五入
	return num;
}

module.exports = arithmetic;